<?php

namespace Addons\CentralControl\WebSocketController;

use Addons\CentralControl\Services\CentralService;
use Addons\CentralControl\Services\ModbusService;
use Common\Context\WebsocketContext;
use Common\Helpers\DebugHelper;
use Common\WebSocketController;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\WebSocketServer\Context as WsContext;
use Hyperf\WebSocketServer\Sender;
use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;

class ZyjController extends WebSocketController
{
    public array $authOptional = [];

    /**
     * @Inject
     * @var CacheInterface
     */
    #[Inject]
    protected CacheInterface $cache;

    /**
     * @Inject
     * @var ConfigInterface
     */
    #[Inject]
    protected ConfigInterface $config;

    /**
     * @var Sender
     */
    #[Inject]
    protected Sender $sender;

    /**
     * 取衣 2
     * @param $data
     * @return array
     * @throws InvalidArgumentException
     */
    function index($data): array
    {
        $zd = $data['zd'];
        $qybh = (int) $data['qybh'];

        DebugHelper::consoleWrite('控制面板-取衣发送指令', $data);

        /**
         * 如果qybh小于0，就从408开始减去
         */
        if ($qybh < 0) {
            $qybh = $qybh + 408;
        }
        $clientid = CentralService::getClientidByCode($zd);

        $key = 'fd_' . $clientid;
        $fd = $this->cache->get($key);
        $com = new ModbusService();
        DebugHelper::consoleWrite('控制面板-发送指令---fd', [
            'fd' => $fd
        ]);


        $numKey = 'qyNum_' . $clientid;
        $oldNum = $this->cache->get($numKey);

        if($oldNum === $qybh){
            return $this->writeJson(200, [], '与上次相同不能重复发送', 'qy_res');
        }

        /**
         * 保存设备状态
         */
        $key = 'devStatus_' . $clientid;
        $devStatus = $this->cache->get($key);

        if ((int) $devStatus === 1){
            return $this->writeJson(400, [], '设备运行中，请稍后再试', 'qy_res');
        }

        /**
         * 使用缓存记录操作次数
         */
        $comNumKey = 'comNum_' . $clientid;
        if ($this->cache->has($comNumKey)) {
            $oldNum = $this->cache->get($comNumKey);
            $this->cache->set($comNumKey, $oldNum+1);
            /**
             * 增加一次减去1，增加2次减去2，增加三次减去6
             */

        }


        $this->cache->set($numKey, $qybh);
        $type = 1;//出口
        $send_com = [
            'type' => 'send_com',
            'data' => [
                'bz'=>1,
                'clientid'=>$clientid,
                'type' =>503,
                'command' => $com->buildModbusCommandNum($qybh, $type)
            ],
            'message' => '取衣指令发送',
        ];
        DebugHelper::consoleWrite('控制面板-发送指令', $send_com);
        $this->sender->push($fd, json_encode($send_com));
        return $this->writeJson(200, [], '准备取衣', 'qy_res');
    }



    /**
     * 挂衣 1
     * @param $data
     * @return array
     */
    public function guayi($data): array
    {
        //        $zd = $data['zd'];
        //        $qybh = $data['gybh']-95;

        /**
         * 如果qybh大于等于408，就从0开始计算偏移
         */
        //        if ($qybh >= 408) {
        //            $qybh =  $qybh - 408;
        //        }

        /**
         * 如果小于0，就从408开始减去
         */
        //        if ($qybh < 0) {
        //            $qybh = $qybh + 408;
        //        }

        //        $clientid = CentralService::getClientidByCode($zd);
        //
        //        $key = 'fd_' . $clientid;
        //        $fd = $this->cache->get($key);


        //        $com = new ModbusService();
        //        DebugHelper::consoleWrite('控制面板-发送指令---fd', [
        //            'fd' => $fd
        //        ]);
        //        $type = 1;
        //        $send_com = [
        //            'type' => 'send_com',
        //            'data' => [
        //                'type' =>503,
        //                'command' => $com->buildModbusCommandNum($qybh,$type)
        //            ],
        //            'message' => '取衣指令发送',
        //        ];
        //        DebugHelper::consoleWrite('控制面板-发送指令', $send_com);
        //        $this->sender->push($fd, json_encode($send_com));
        return $this->writeJson(200, [], '准备取衣', 'guayi_res');
    }

    function getStatus($data)
    {
        $zd = $data['zd'];
        $clientid = CentralService::getClientidByCode($zd);
        /**
         * 保存设备状态
         */
        $key = 'devStatus_' . $clientid;
        $devStatus = $this->cache->get($key);
        return $this->writeJson(200, [
            'devStatus' => $devStatus
        ], '状态查询成功', 'getStatus_res');
    }

    /**
     * 监听当前设备状态1为运行中0为结束
     * @param $data
     * @return array
     * @throws InvalidArgumentException
     */
    function status($data): array
    {
        $zd = $data['zd'];
        DebugHelper::consoleWrite('控制面板状态-获取当前面板实时状态数据', [
            'data' => $data
        ]);
        $type = (int) $data['typeNum'];
        if (!in_array($type, [503,505])){
            return $this->writeJson(500, [], '参数错误', 'status_res');
        }

        $clientid = CentralService::getClientidByCode($zd);

        $key = 'fd_' . $clientid;
        $fd = $this->cache->get($key);


        $com = new ModbusService();
        DebugHelper::consoleWrite('控制面板状态--发送指令---fd', [
            'fd' => $fd
        ]);

        $send_com = [
            'type' => 'send_com_status',
            'data' => [
                'command' => $com->buildModbusCommandStatus($type)
            ],
            'message' => '监听指令发送',
        ];
        DebugHelper::consoleWrite('控制面板状态--发送指令', $send_com);
        $this->sender->push($fd, json_encode($send_com));
        return $this->writeJson(200, [], '准备监听', 'status_res');
    }

    function deviceinit($Args): array
    {
        try {
            $clientid = $Args['clientid'];
            $name = $Args['name'];
            $project_id = WebsocketContext::getContext(WebsocketContext::PROJECT_ID);
            $Res = CentralService::saveDeviced($project_id, $clientid, $name);
            return $this->writeJson(200, $Res, '设备初始化成功', 'deviceInit_res');
        } catch (\Exception $e) {
            DebugHelper::consoleWrite('设备初始化失败', $e->getMessage());
        }

        return $this->writeJson(500, [], '设备初始化失败');
    }

    function upfd($device_data): array
    {
        try {
            $fd = WebsocketContext::getContext(WsContext::FD);
            $key = 'fd_' . $device_data['clientid'];
            $this->cache->set($key, $fd);
            DebugHelper::consoleWrite('收到设备信息-更新fd', $device_data);
//            $Res = CentralService::upDevicedFd($fd, $device_data['clientid']);
            $Res = CentralService::getDevicedByClientId($device_data['clientid']);
            $Res['websocket_fd'] = $fd;

            /**
             * 保存设备状态
             */
            $devStatus = $device_data['devStatus'];
            $key = 'devStatus_' . $device_data['clientid'];
            $this->cache->set($key, $devStatus);

            return $this->writeJson(200, $Res, '更新Fd成功', 'upfd_res');
        } catch (\Exception $e) {
            DebugHelper::consoleWrite('更新Fd失败', $e->getMessage());
        }
        return $this->writeJson(500, [], '更新Fd失败');
    }

    function deviceinfo($device_data): array
    {
        $Res = CentralService::getDevicedByClientId($device_data['clientid']);
        return $this->writeJson(200, [
            'Res' => $Res
        ], '更新Fd成功');
    }

    public function onClose($server, int $fd, int $reactorId): void
    {
        // TODO: Implement onClose() method.
    }

    public function onMessage($server, $frame): void
    {
        DebugHelper::consoleWrite('控制面板-收到消息', $frame->data);
        // TODO: Implement onMessage() method.
    }

    public function onOpen($server, $request): void
    {
        // TODO: Implement onOpen() method.
    }
}